/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
var data = {
    inputedIp: "",
    appState: "Connecting to Device",
    keyboardName: "fcCtrl",
    selectDevice: false,
    showSmartConfigWindow: false,
    showSmardPasswordWindow: false,
    log: "",
    showLog: false,
    connectingWifi: {},
    wifi: [{
        "level": 1, // raw RSSI value
        "SSID": "ssid", // SSID as string, with escaped double quotes: "\"ssid name\""
        "BSSID": "bssid", // MAC address of WiFi router as string
        "frequency": 20, // frequency of the access point channel in MHz
        "capabilities": "KEY" //capabilities // Describes the authentication, key management, and encryption schemes supported by the access point.
    }, {
        "level": 2, // raw RSSI value
        "SSID": "ssid1", // SSID as string, with escaped double quotes: "\"ssid name\""
        "BSSID": "bssid2", // MAC address of WiFi router as string
        "frequency": 21, // frequency of the access point channel in MHz
        "capabilities": "KEY1" //capabilities // Describes the authentication, key management, and encryption schemes supported by the access point.
    }],
    devices: [{
        connectionState: "none",
        "domain": "local.",
        "type": "_arduino._tcp.",
        "name": "arduino9bc196",
        "port": 80,
        "hostname": "",
        "ipv4Addresses": ["192.188.1.102"],
        "ipv6Addresses": [],
        "txtRecord": {
            "distro_name": "esplink",
            "ssh_upload": "no",
            "distro_version": "0.1",
            "board": "unowifi",
            "vendor ": " Espressif",
            "tcp_check": "yes",
            "auth_upload": "no"
        }
    }, {
        connectionState: "none",
        "domain": "local.",
        "type": "_arduino._tcp.",
        "name": "arduino9bc196",
        "port": 80,
        "hostname": "",
        "ipv4Addresses": ["192.188.1.102"],
        "ipv6Addresses": [],
        "txtRecord": {
            "distro_name": "esplink",
            "ssh_upload": "no",
            "distro_version": "0.1",
            "board": "unowifi",
            "vendor ": " Espressif",
            "tcp_check": "yes",
            "auth_upload": "no"
        }
    }]
};
window.zeroconf = null;
var app = new Vue({
    el: '#app',
    data: data,
    computed: {
        mainDropdownColor: function () {
            if (this.socket) {
                if (this.socket.state === Socket.State.OPENED) {
                    return "green";
                } else if (this.socket.state === Socket.State.OPENING) {
                    return "yellow";
                }
            }
            return "black";
        }
    },
    methods: {
        stopConnectingWifi:function(){
            this.showSmardPasswordWindow = false;
            data.connectingWifi = {};
            espSmartconfig.stopConfig();
        },
        connectWifi:function(){
            var password = data.connectingWifi.password;
            var ws = data.connectingWifi.wifi;
            espSmartconfig.startConfig(ws.SSID, ws.BSSID, password, "notUsed", "0", function (res) {
                alert(res);
            }, function (error) {
                console.log(error);
            });
        },
        configWifi: function (wifi) {
            console.log("wifi:" + JSON.stringify(wifi));
            espSmartconfig.stopConfig();
            var ws = data.wifi.find(function (w) {
                return w.SSID === wifi;
            });
            if (ws) {
                data.connectingWifi = {
                    password: "",
                    wifi: ws
                };
                this.showSmardPasswordWindow = true;
            }
        },
        UseInputIP: function () {
            var ip = data.inputedIp;
            var dev = {
                name: "inputed",
                ipv4Addresses: [ip]
            };
            this.makeConnection(dev);
        },
        buttonDown: function (evt) {
            var target = evt.target;
            var keycode = target.dataset.keycode;
            console.log("button down:" + keycode);
            //$(this.$el).addClass('showHelp');
            $(target).addClass('showHelp');
            this.sendMessage("keydown", keycode);
        },
        buttonUp: function (evt) {
            var target = evt.target;
            var keycode = target.dataset.keycode;
            console.log("button up:" + keycode);
            $(this.$el).removeClass('showHelp');
            $(target).removeClass('showHelp');
            this.sendMessage("keyup", keycode);
        },
        sendMessage: function (evtName, keycode) {
            if (this.connection && this.connection.socket.state == Socket.State.OPENED) {
                var dataString = nuoding.hardware.Message.make({
                    type: "system",
                    name: evtName,
                    value: {
                        keyCode: keycode
                    }
                });
                var data = new Uint8Array(dataString.length);
                for (var i = 0; i < data.length; i++) {
                    data[i] = dataString.charCodeAt(i);
                }
                this.connection.socket.write(data);
            }
        },
        getDevice: function (name) {
            return data.devices.find((d) => {
                return d.name === name;
            });
        },
        makeConnection: function (dev) {
            var socket = new Socket();
            this.connection = {
                device: dev,
                socket: socket
            };
            dev.connectionState = "connecting";
            socket.open(dev.ipv4Addresses[0], 23, function () {
                data.showLog = false;
                dev.connectionState = "connected";
            }, function (err) {
                var str = JSON.stringify(err);
                data.log = str;
                data.showLog = true;
                dev.connectionState = "error";
                dev.error = str;
            });
        },
        connectDevice: function (t) {
            if (t === "Inputed") {
                return;
            }
            //this.backToMain();
            if (this.connection) {
                this.connection.socket.close();
                this.connection.device.connectionState = "none";
                this.connection = null;
            }
            var dev = this.getDevice(t);
            this.makeConnection(dev);
        },
        useCtrl: function (name) {
            data.keyboardName = name;
            setTimeout(function () {
                var board = $('#' + name).first();
                var img = $('#' + name + '>.bg').first();
                //board.css('background-image', 'url(' + img + ')');
                // var image = new Image();
                // image.src = img;
                //image.onload(function () {
                setTimeout(function () {
                    var img = $('#' + name + '>.bg').first();
                    var imgWidth = img.width();
                    var imgHeight = img.height();
                    var keyboardLayout = $('#' + name + '>.keyboardLayout').first();
                    keyboardLayout.width(imgWidth);
                    keyboardLayout.height(imgHeight);
                }, 5);
                //});
            }, 5);
        },
        mainDropdownMethod: function (name) {
            if (this[name]) {
                this[name]();
            } else {
                this.useCtrl(name);
            }
        },
        smartConfig: function () {
            this.showSmartConfigWindow = true;
            data.wifi = [];
            if (window.espSmartconfig) {
                espSmartconfig.getNetworklist({
                    numLevels: 5
                }, function (wifiPoint) {
                    data.wifi = wifiPoint.concat(data.wifi);
                }, function (e) {
                    console.log(e);
                });
            }
        },
        backToMain: function () {
            data.showSmartConfigWindow = false;
            data.selectDevice = false;
            if (zeroconf) {
                data.devices = [];
                zeroconf.close();
            }
            if (window.espSmartconfig) {
                espSmartconfig.stopConfig();
            }
        },
        openDeviceList: function () {
            data.selectDevice = true;
            this.startMDNS();
        },
        // Application Constructor
        initialize: function () {
            if (window.cordova) {
                document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
            } else {
                $('#loading').remove();
            }
            this.useCtrl(data.keyboardName);
            $(window).resize(function () {
                app.useCtrl(data.keyboardName);
            });
        },

        // deviceready Event Handler
        //
        // Bind any cordova events here. Common events are:
        // 'pause', 'resume', etc.
        onDeviceReady: function () {
            window.screen.orientation.lock('portrait');
            window.zeroconf = cordova.plugins.zeroconf;

            //For Android, you may want set the following options to speed discovery up:
            zeroconf.registerAddressFamily = 'ipv4'; // or 'ipv6' ('any' by default)
            zeroconf.watchAddressFamily = 'ipv4'; // or 'ipv6' ('any' by default)
            data.devices = [];
            data.appState = 'device ready';
            $('#loading').remove();
        },
        startMDNS: function () {
            if (!zeroconf) {
                return;
            }
            /*
            {
                "action": "resolved",
                "service": {
                    "domain": "local.",
                    "type": "_arduino._tcp.",
                    "name": "arduino9bc196",
                    "port": 80,
                    "hostname": "",
                    "ipv4Addresses": ["192.188.1.102"],
                    "ipv6Addresses": [],
                    "txtRecord": {
                        "distro_name": "esplink",
                        "ssh_upload": "no",
                        "distro_version": "0.1",
                        "board": "unowifi",
                        "vendor ": " Espressif",
                        "tcp_check": "yes",
                        "auth_upload": "no"
                    }
                }
            }
            */
            zeroconf.watch('_arduino._tcp.', 'local.', function (result) {
                data.appState = JSON.stringify(result);
                var action = result.action;
                var service = result.service;
                if (action == 'added') {
                    console.log('service added', service);
                } else if (action == 'resolved') {
                    console.log('service resolved', service);
                    service.connectionState = "none";
                    data.devices.push(service);
                    /* service : {
                    'domain' : 'local.',
                    'type' : '_http._tcp.',
                    'name': 'Becvert\'s iPad',
                    'port' : 80,
                    'hostname' : 'ipad-of-becvert.local',
                    'ipv4Addresses' : [ '192.168.1.125' ], 
                    'ipv6Addresses' : [ '2001:0:5ef5:79fb:10cb:1dbf:3f57:feb0' ],
                    'txtRecord' : {
                        'foo' : 'bar'
                    } */
                } else {
                    console.log('service removed', service);
                    var i = data.devices.findIndex(function (dev) {
                        return dev.name === service.name;
                    });
                    data.devices.splice(i, 1);
                }
            });
        }
    }
});

app.initialize();